//============================================================================
// Name        : ServerMatch.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fstream>
#include <iostream>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <semaphore.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "manejadorGrilla.h"
#include "personajes/cPrincesa.h"
#include "personajes/cJugador.h"
#include "personajes/cMono.h"
#include "personajes/cFuego.h"
#include "personajes/cBarril.h"
#include "clasesAuxiliares/SocketCommunication.h"
#include "clasesAuxiliares/envioAlCliente.h"
#include <queue>
////////////////////////////////////////  estructura memoria compartida /////////////////////////////////////////////////
#define MAXCLI 10
#define TAMBUF 26

typedef struct{
	int  id,socket,
		 puntaje,
		 disponible,
		 cantPartidas,
		 conectado,
		 posicionEnTorneo; //1 conectado puntaje dentro del torneo
	char nombre[10];

}t_jugador;

typedef struct{
	int  pid,
	     jugador1,
	     jugador2,
	     terminoPartida,
	     jugadorGanador; //ganador (1 o 2)
}t_partida;

typedef struct{
	t_jugador jugador[MAXCLI];
	int cantPartidas;
	t_partida partidas[50];
	int cantJugadores;
	int t_chequeo;
	int tiempo_torneo;
	int tiempo_espera_conex_max;
	int nivel_dificultad;
	int cantidad_rescates;
	//int flagFinConexiones;
	int partidaCaida; //1 se cayo la partida
}t_torneo;




//#include <time.h>

using namespace std;

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int GRILLA_WIDTH = 64;
const int GRILLA_HEIGHT = 48;

const int MAX_BARRILES = 10;
const int MAX_FUEGO = 10;

//senial
const int ARRIBA = 1;
const int IZQUIERDA = 2;
const int DERECHA = 3;
const int ABAJO = 4;
const int SALTO_ARRIBA = 5;
const int SALTO_IZQUIERDA = 6;
const int SALTO_DERECHA = 7;

const int OCULTAR_ELEMENTO = 100;

// valores de objetos en la grilla;
const int OBJ_PISO = 9;

//creo el semanforo de envio
//sem_t mutex_envio;

SocketCommunication * commSocket_J1;
SocketCommunication * commSocket_J2;

manejadorGrilla partida;

//creamos los personajes
cPrincesa * princesa = new cPrincesa();
cJugador * jugador2 = new cJugador(2);
cJugador * jugador1 = new cJugador(1);
cMono * mono = new cMono();
//creo los fuegos fijos...
cFuego * fuegoFijoIzq = new cFuego();
cFuego * fuegoFijoDer = new cFuego();
//lo tengo que hacer con un random con la complejidad del juego...
cFuego * fuegos = new cFuego[MAX_FUEGO];
cBarril * barriles = new cBarril[MAX_BARRILES];

pthread_t movementThread;
pthread_t keysThreadJ1;
pthread_t keysThreadJ2;


//variable global para guardar el id de la memoria compartida.
int id_memo;
//variable global para acceder a los datos de torneo.
t_torneo *torneo;
//variable global para el semaforo de la memoria
sem_t *semMemoria;

bool finPartida;
int finAbrupto;
int nivelDificultad;
int cantidadRescates;


void *movimientoPersonajes(void *);
void *recepcionTeclasJ1(void *);
void *recepcionTeclasJ2(void *);

void crearMemoriaCompartida(key_t clave);
void crearSemaforos();
void liberarRecursos();


//void establecerComunicacionConClientes(char *, char *, char *, char *);
void inicializarPersonajes();
int evaluarColisionPrinJugador();
int evaluarColisionMonoJugador();
int evaluarColisionBarrilJugador(int);
int evaluarColisionFuegoJugador(int);
void movimientoJugador(int, cJugador *);
bool colision(int, int, int, int, int, int, int, int);
void capturarSeniales();

void handler_signal(int sig, siginfo_t *info, void *ni)
{
	printf("llegooooooo la señal SIGUSR1  a la partida. \n");
	envioAlCliente::envioFinJuego(commSocket_J1, commSocket_J2);

	//commSocket_J1->SendBloq((char *)"mt", TAMBUF);
	//commSocket_J2->SendBloq((char *)"mt", TAMBUF);
	//commSocket_J1->SendBloq((char *)"mt", TAMBUF);
	//commSocket_J2->SendBloq((char *)"mt", TAMBUF);

	usleep(3500);
	//FUNCIONA PERO NO ES OPTIMO ESTO. NI ESTETICO.
	int i;
    char respuesta[TAMBUF];
    respuesta[TAMBUF] = '\0';
    memset(&respuesta,'\0',TAMBUF);
    strncpy(respuesta,"mt",TAMBUF);

	sem_wait(semMemoria);
	for (i=0;i<torneo->cantJugadores;i++)
	{
		if(torneo->jugador[i].conectado !=0){
			send(torneo->jugador[i].socket , (char *)respuesta , TAMBUF , 0);
			send(torneo->jugador[i].socket , (char *)respuesta , TAMBUF , 0);
			close(torneo->jugador[i].socket);
			//printf("CERRADOS %d   ",torneo->jugador[i].socket);
		}
	}
	sem_post(semMemoria);

	liberarRecursos();

	exit(1);

}


//Capturamos las señales
void capturarSeniales()
{
	struct sigaction act;
	act.sa_sigaction = handler_signal;
	//bloqueamos las señales.
	sigemptyset(&act.sa_mask);
	sigfillset(&act.sa_mask);
	act.sa_flags = SA_SIGINFO;
	sigaction(SIGUSR1,&act,NULL);

	signal(SIGINT,SIG_IGN);
	signal(SIGTERM,SIG_IGN);
	//signal(SIGSTOP,SIG_IGN);
	//signal(SIGKILL,SIG_IGN);
	signal(SIGABRT,SIG_IGN);
	signal(SIGHUP,SIG_IGN);
	signal(SIGPIPE,SIG_IGN);
	signal(SIGQUIT,SIG_IGN);
	signal(SIGSEGV,SIG_IGN);
	//signal(SIGUSR1,handler_signal);
	signal(SIGUSR2,SIG_IGN);
	//GP
	signal(SIGALRM,SIG_IGN);
}


void crearMemoriaCompartida(key_t clave){

	//genero memoria compartida.
	id_memo = shmget(clave,sizeof(t_torneo),IPC_CREAT | 0666);
	//printf ("id_memo Torneo %d\n", id_memo);
	if(id_memo < 0) {
			std::cout << "No consigo clave para memoria compartida" << endl;
			exit(EXIT_FAILURE);
		}

	torneo = (t_torneo *) shmat(id_memo,NULL,0);
}
void crearSemaforos()
{
	sem_unlink("/semMemoria");

	semMemoria = sem_open("/semMemoria",O_CREAT,0644,1);
	if(semMemoria == SEM_FAILED) {
		cerr << "Error: habilita para crear semaforos!!" << endl;
		exit(EXIT_FAILURE);
	}
}

void liberarRecursos()
{
	puts("SERVER MATCH .. Liberando semáforos y memoria compartida");

/*	shmdt((t_torneo *)torneo);
	sem_close(semMemoria);

	sem_unlink("/semMemoria");
*/
	//exit(1);
}

bool colision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
	if ((x1 >= x2 && x1 <= (x2 + w2))
			|| ((x1 + w1) >= x2 && (x1 + w1) <= (x2 + w2)))
		if ((y1 >= y2 && y1 <= (y2 + h2))
				|| ((y1 + h1) >= y2 && (y1 + h1) <= (y2 + h2)))
			return true;

	return false;
}

int evaluarColisionPrinJugador() {
	if (colision(jugador1->x, jugador1->y, jugador1->witdh, jugador1->height,
			princesa->x, princesa->y, princesa->witdh, princesa->height))
		return 1;

	if (colision(jugador2->x, jugador2->y, jugador2->witdh, jugador2->height,
			princesa->x, princesa->y, princesa->witdh, princesa->height))
		return 2;

	return 0;
}

int evaluarColisionMonoJugador() {
	if (colision(jugador1->x, jugador1->y, jugador1->witdh, jugador1->height,
			mono->x, mono->y, mono->witdh, mono->height))
		return 1;

	if (colision(jugador2->x, jugador2->y, jugador2->witdh, jugador2->height,
			mono->x, mono->y, mono->witdh, mono->height))
		return 2;

	return 0;
}

int evaluarColisionBarrilJugador(int i) {
	if (colision(jugador1->x, jugador1->y, jugador1->witdh, jugador1->height,barriles[i].x, barriles[i].y, barriles[i].witdh,	barriles[i].height))
		return 1;

	if (colision(jugador2->x, jugador2->y, jugador2->witdh, jugador2->height,
			barriles[i].x, barriles[i].y, barriles[i].witdh,
			barriles[i].height))
		return 2;

	return 0;
}

int evaluarColisionFuegoJugador(int i) {
	if (colision(jugador1->x, jugador1->y, jugador1->witdh, jugador1->height,
			fuegos[i].x, fuegos[i].y, fuegos[i].witdh, fuegos[i].height))
		return 1;

	if (colision(jugador2->x, jugador2->y, jugador2->witdh, jugador2->height,
			fuegos[i].x, fuegos[i].y, fuegos[i].witdh, fuegos[i].height))
		return 2;

	return 0;
}

void *recepcionTeclasJ1(void *) {
	envio recepcion_teclas;
	int senial = 0;
	while (!finPartida) {
		if (commSocket_J1->ID != 0) {
			if (commSocket_J1->ReceiveBloq(&recepcion_teclas, sizeof(envio)) == 0)
			{
				finPartida = true;
			}
			else
			{
				senial = atoi(recepcion_teclas.senial);
				if(senial == 0)
				{
					finAbrupto = 1;
					finPartida = true;
				}
				else
					movimientoJugador(senial, jugador1);
			}
		}
	}
	pthread_exit(NULL);
	return (void*) NULL;
}

void *recepcionTeclasJ2(void *) {
	envio recepcion_teclas;
	int senial = 0;
	while (!finPartida) {
		if (commSocket_J2->ID != 0) {
			if (commSocket_J2->ReceiveBloq(&recepcion_teclas, sizeof(envio)) == 0)
			{
				finPartida = true;
			}
			else
			{
				senial = atoi(recepcion_teclas.senial);
				if(senial == 0)
				{
					finAbrupto = 2;
					finPartida = true;
				}
				else
					movimientoJugador(senial, jugador2);
			}
		}
	}
	pthread_exit(NULL);
	return (void*) NULL;
}

void movimientoJugador(int senial, cJugador * jug) {
	switch (senial) {
	case ARRIBA:
		jug->MoverArribaEscalera(partida);
		//std::cout << "ARRIBA" <<std::endl;
		break;
	case ABAJO:
		jug->MoverAbajoEscalera(partida);
		//std::cout << "ABAJO" <<std::endl;
		break;
	case IZQUIERDA:
		jug->moverIzquierda(partida);
		//std::cout << "IZQUIERDA" <<std::endl;
		break;
	case DERECHA:
		jug->moverDerecha(partida);
		//std::cout << "DERECHA" <<std::endl;
		break;
	case SALTO_ARRIBA:
		jug->SaltarArriba(partida);
		//std::cout << "SALTAR ARRIBA" <<std::endl;
		break;
	case SALTO_IZQUIERDA:
		jug->SaltarIzquierda(partida);
		std::cout << "SALTAR IZQUIERDA" <<std::endl;
		break;
	case SALTO_DERECHA:
		jug->SaltarDerecha(partida);
		std::cout << "SALTAR DERECHA" <<std::endl;
		break;
	default:
		break;
	}
}

void *movimientoPersonajes(void * aux) {
	//tengo que crear un random entre 10 y 30 para ver cuando creo los barriles...
	//esto esta atado a la complejidad del juego...
	int randomCreacionBarril = (4 - nivelDificultad) * 30; //hago un random y multiplico por un numero para que aparezcan cada tanto
	int randomCreacionFuego = (4 - nivelDificultad) * 45;
	int auxRandomCreacionFuego = randomCreacionFuego;
	int auxRandomCreacionBarril = randomCreacionBarril;
	bool encontrado;
	int auxCantBarriles = 0;
	int auxCantFuego = 0;

	//colisiones
	int colPrincesaJugador = 0;
	int colFuegoJugador = 0;
	int colBarrilJugador = 0;
	int colMonoJugador = 0;
	bool fin;

	usleep(2000000); //freno el juego antes de empezar
	while (!finPartida) {
		//std::cout << "Inicio partida" << std::endl;
		//reseteo las colisiones
		colBarrilJugador = 0;
		colFuegoJugador = 0;
		colMonoJugador = 0;
		colPrincesaJugador = 0;
		fin = false;
		while (!fin && !finPartida) {
			usleep(200000);

			if (auxRandomCreacionBarril == 0) {
				//reinicio la creacion de barril...
				auxRandomCreacionBarril = randomCreacionBarril;

				//llego el momento de crear un barril
				encontrado = false;
				//busco un lugar vacio en el vector de barriles y si hay alguno libre lo creo...
				while (!encontrado) {
					//solo permite la creacion de hasta MAX_BARRILES por pantalla...
					if (auxCantBarriles < MAX_BARRILES) {
						if (barriles[auxCantBarriles].fin == true) {
							encontrado = true;
							barriles[auxCantBarriles] = cBarril();
							//std::cout << "Creo Barril (" << auxCantBarriles	<< ")" << std::endl;
							barriles[auxCantBarriles].Inicializar(partida,	mono->x, mono->y, auxCantBarriles,	commSocket_J1, commSocket_J2);
						} else
							auxCantBarriles++;
					} else
						encontrado = true;
				}

				//reinicio..
				auxCantBarriles = 0;
				encontrado = false;
			} else {
				auxRandomCreacionBarril--;
			}

			//Crecion de los fuegos aleatoriamente
			if (auxRandomCreacionFuego == 0) {
				//reinicio la creacion de barril...
				auxRandomCreacionFuego = randomCreacionFuego;

				encontrado = false;
				while (!encontrado) {
					//solo permite la creacion de hasta MAX_BARRILES por pantalla...
					if (auxCantFuego < MAX_FUEGO) {
						if (fuegos[auxCantFuego].fin == true) {
							encontrado = true;
							fuegos[auxCantFuego] = cFuego();
							fuegos[auxCantFuego].InicializarAleatorio(partida,	auxCantFuego, commSocket_J1, commSocket_J2);
							//std::cout << "Creo Fuego (" << auxCantFuego << ")"<< std::endl;
						} else
							auxCantFuego++;
					} else
						encontrado = true;
				}

				//reinicio..
				auxCantFuego = 0;
				encontrado = false;
			} else {
				auxRandomCreacionFuego--;
			}

			jugador1->mover(partida);
			jugador2->mover(partida);

			if (!fin) {
				princesa->mover(partida);
				colPrincesaJugador = evaluarColisionPrinJugador();
				if (colPrincesaJugador > 0)
					fin = true;

				////std::cout << "Princesa (" << princesa->x << "," << princesa->y << ") "<< std::endl;
				if(princesa->restrasoMovimiento == 1)
					envioAlCliente::envioPosicion(princesa->id, commSocket_J1,	commSocket_J2, princesa->x, princesa->y);
			}

			if (!fin) {
				mono->mover(partida);
				colMonoJugador = evaluarColisionMonoJugador();
				if (colMonoJugador > 0)
					fin = true;
				////std::cout << "Mono (" << mono->x << "," << mono->y << ") "<< std::endl;
				if(mono->restrasoMovimiento == 2)
					envioAlCliente::envioPosicion(mono->id, commSocket_J1,	commSocket_J2, mono->x, mono->y);
			}

			if (!fin) {
				//movimiento de barriles
				for (int i = 0; i < MAX_BARRILES; i++) {
					if (barriles[i].fin == false && !fin) {
						barriles[i].mover(partida);
						colBarrilJugador = evaluarColisionBarrilJugador(i);
						if (colBarrilJugador > 0)
						{
							barriles[i].Desactivar();
							fin = true;
						}
						else
							envioAlCliente::envioPosicion(barriles[i].id,commSocket_J1, commSocket_J2, barriles[i].x,barriles[i].y);
						////std::cout << "Barril[" << i << "]: (" << barriles[i].x << "," << barriles[i].y << ") "<< std::endl;
						////std::cout << barriles[i].id << " - " << barriles[i].x << " , " << barriles[i].y << std::endl;
					}
				}
			}

			if (!fin) {
				//movimiento de fuegos
				for (int i = 0; i < MAX_FUEGO; i++) {
					if (fuegos[i].fin == false && !fin) {
						fuegos[i].mover(partida);
						colFuegoJugador = evaluarColisionFuegoJugador(i);
						if (colFuegoJugador > 0)
						{
							fuegos[i].Desactivar();
							fin = true;
						}
						else
							envioAlCliente::envioPosicion(fuegos[i].id,	commSocket_J1, commSocket_J2, fuegos[i].x,	fuegos[i].y);
					}
				}
			}
		} // FIN WHILE MOVIMIENTOS

		//std::cout << "FIN WHILE MOVIMIENTOS" << std::endl;


		if (colPrincesaJugador > 0) {
			if (colPrincesaJugador == 1) {
				envioAlCliente::envioRescatePrincesa(jugador1->cId,	commSocket_J1, commSocket_J2);
				jugador1->rescates++;
				std::cout << "	RESCATE: " << jugador1->cId << std::endl;
			} else {
				envioAlCliente::envioRescatePrincesa(jugador2->cId,	commSocket_J1, commSocket_J2);
				jugador2->rescates++;
				std::cout << "	RESCATE: " << jugador2->cId << std::endl;
			}

			if (jugador1->rescates >= cantidadRescates || jugador2->rescates >= cantidadRescates) {
				finPartida = true; //esto quiere decir que se termino el juego porque la princesa fue salvada 3 veces...

				//envio env;
				//strcpy(env.identificador,"fin");
				//sprintf(env.tipo_senial, "%d",10);//FIN_JUEGO;
				//env.tipo_senial = 10; //FIN_JUEGO;
				//usleep(8500);

				//while (send(commSocket_J1->ID,&env,sizeof(env),0) == -1);  //MSG_CONFIRM);
				//while (send(commSocket_J2->ID,&env,sizeof(env),0) == -1);  //MSG_CONFIRM);

				//commSocket_J1->SendBloq(&env, sizeof(env));
				//commSocket_J2->SendBloq(&env, sizeof(env));
				std::cout <<  "FIN JUEGO" << std::endl;

				envioAlCliente::envioFinJuego(commSocket_J1, commSocket_J2);
				usleep(1000);
				std::cout << "	ENVIO FIN JUEGO: " << std::endl;
			} else {
				jugador1->inicializar(commSocket_J1, commSocket_J2);
				jugador2->inicializar(commSocket_J1, commSocket_J2);

				inicializarPersonajes();

			}
		}

		if (colFuegoJugador > 0 || colMonoJugador > 0 || colBarrilJugador > 0) {
			if (colFuegoJugador == 1 || colMonoJugador == 1	|| colBarrilJugador == 1) {
				envioAlCliente::envioRestarVidas(jugador1->cId, commSocket_J1,commSocket_J2,jugador1->vidas);
				jugador1->vidas--;
				jugador1->inicializar(commSocket_J1, commSocket_J2);
//				std::cout << "	ENVIO RESTAR VIDA: " << jugador1->cId << std::endl;

			}

			if (colFuegoJugador == 2 || colMonoJugador == 2	|| colBarrilJugador == 2) {
				envioAlCliente::envioRestarVidas(jugador2->cId, commSocket_J1,commSocket_J2, jugador2->vidas);
				jugador2->vidas--;
				jugador2->inicializar(commSocket_J1, commSocket_J2);
//				std::cout << "	ENVIO RESTAR VIDA: " << jugador2->cId << std::endl;
			}

			if (jugador1->vidas == 0 || jugador2->vidas == 0) {
				finPartida = true; //esto quiere decir que se quedo sin vidas, terima la partida...
				usleep(1000);

				//envio env;
				//strcpy(env.identificador,"fin");
				//sprintf(env.tipo_senial, "%d",10);//FIN_JUEGO;
				//env.tipo_senial = 10; //FIN_JUEGO;
				//usleep(8500);

				//while (send(commSocket_J1->ID,&env,sizeof(env),0) == -1);  //MSG_CONFIRM);
				//while (send(commSocket_J2->ID,&env,sizeof(env),0) == -1);  //MSG_CONFIRM);

				//commSocket_J1->SendBloq(&env, sizeof(env));
				//commSocket_J2->SendBloq(&env, sizeof(env));
				std::cout <<  "FIN JUEGO" << std::endl;


				envioAlCliente::envioFinJuego(commSocket_J1, commSocket_J2);
				std::cout << "	ENVIO FIN JUEGO " << std::endl;
			}
		}
	} //FIN WHILE PARTIDA

	//std::cout << "****** FIN JUEGO ****" << std::endl;

	if(finAbrupto > 0)
	{
		usleep(20000);
		envioAlCliente::envioFinJuego(commSocket_J1, commSocket_J2);
	}

	pthread_exit(NULL);
	return (void*) NULL;
}

//void establecerComunicacionConClientes(char * ipJug1, char* puertoJug1,char* ipJug2, char* puertoJug2) {
//
//	try {
//		commSocket_J1 = new SocketCommunication(atoi(puertoJug1), ipJug1);
//	} catch (const char * err) {
//		std::cout << "ERROR Socket Jugador 1: " << err << std::endl;
//		exit(1);
//	}
//
//	try {
//		commSocket_J2 = new SocketCommunication(atoi(puertoJug2),ipJug2);
//
//	} catch (const char * err) {
//		std::cout << "ERROR Socket Jugador 2: " << err << std::endl;
//	}
//}

void inicializarPersonajes() {
	try {
		//std::cout << "INICIALIZANDO PERSONAJES" << std::endl;

		//inicializo los objetos fijos...
		princesa->inicializar(partida, 1, commSocket_J1, commSocket_J2);
		mono->inicializar(partida, 1, commSocket_J1, commSocket_J2);

		for (int i = 0; i < MAX_BARRILES; i++)
			barriles[i].Desactivar();

		for (int i = 0; i < MAX_FUEGO; i++)
			fuegos[i].Desactivar();

		//	fuegoFijoIzq->InicializarFijo(partida,29,43,1, commSocket_J1, commSocket_J2);
		//	fuegoFijoDer->InicializarFijo(partida,33,43,2, commSocket_J1, commSocket_J2);
	} catch (const char * err) {
		//std::cout << "ERROR Socket Jugador 2: " << err << std::endl;
		exit(1);
	}
}

int main() {

	int ganadorPartida;
	sigset_t intmask;
	sigemptyset(&intmask);
	sigaddset(&intmask, SIGUSR1);
	sigprocmask(SIG_UNBLOCK, &intmask,NULL);

	capturarSeniales();

	commSocket_J1 = new SocketCommunication();
	commSocket_J2 = new SocketCommunication();

	/*
//  ESTO SE AGREGA PARA LA EJECUCUCION SOLO CON UN CLIENTE ***

	int puertoJug1 = 5656;
	char ipJug1[20];
	strcpy(ipJug1,"127.0.0.1");
	commSocket_J1 = new SocketCommunication(atoi("5656"), ipJug1);
	commSocket_J2 = 0;
*/

	//  ESTO SE AGREGA PARA LA EJECUCUCION SOLO CON UN CLIENTE ***


	// CODIGO COMENTADO PARA EJECUTAR CON CLIENTE

	//obtengo mi PID para conectarme a memoria compartida
	int i,miPid;
	miPid = getpid();

	std::cout << "0 " << std::endl;

	//genero la llave para la memoria compartida
	key_t clave;
	clave = ftok("/bin/cp",222);
	std::cout << "clave: " << clave << endl;
	if(clave == 0)
	{
		std::cout << "No consigo clave para memoria compartida" << endl;
		exit(EXIT_FAILURE);
	}

	crearMemoriaCompartida(clave);
	crearSemaforos();

	sem_wait(semMemoria);
	nivelDificultad = 99;
	nivelDificultad = torneo->nivel_dificultad;
	cantidadRescates = torneo->cantidad_rescates;

	std::cout << "dato dificultad: " <<  torneo->nivel_dificultad<< std::endl;
	for(int i = 0; i < torneo->cantPartidas; i++)
	{
		if(torneo->partidas[i].pid == miPid)
		{
			if(torneo->jugador[torneo->partidas[i].jugador1].socket > 0)
			{
				commSocket_J1->ID = torneo->jugador[torneo->partidas[i].jugador1].socket;
				std::cout << "socket 1: " << commSocket_J1->ID << std::endl;
			}
			else
			{
				std::cout << "NO SE PEUEDE LEER EL SOCKET DEL JUGADOR 1 " << std::endl;
			}

			if(torneo->jugador[torneo->partidas[i].jugador2].socket > 0)
			{
				commSocket_J2->ID = torneo->jugador[torneo->partidas[i].jugador2].socket;
				std::cout << "socket 2: " << commSocket_J1->ID << std::endl;
			}
			else
			{
				std::cout << "NO SE PEUEDE LEER EL SOCKET DEL JUGADOR 2 " << std::endl;
			}
		}
	}
	sem_post(semMemoria);






	//nivelDificultad = 1;
	//CODIGO COMENTADO PARA EJECUTAR CON CLIENTE



	jugador2->inicializar(commSocket_J1, commSocket_J2);
	jugador1->inicializar(commSocket_J1, commSocket_J2);

	inicializarPersonajes();
	finPartida = false;


	//recepcionTeclasJ1(NULL);

	//movimientoPersonajes(NULL);

	//creo el thread de los movimientos de los personajes...
	if (pthread_create(&movementThread, NULL, movimientoPersonajes, NULL) < 0) {
		//std::cout << "00000" << std::endl;
		perror("ERROR no se pudo crear el thread movementThread");
		return 1;
	}

	//creo el thread que recibe las teclas y mueve los jugadores...
	if (pthread_create(&keysThreadJ1, NULL, recepcionTeclasJ1, NULL) < 0) {
		perror("ERROR no se pudo crear el thread recepcionTeclasJ1");
		return 1;
	}


	//CODIGO COMENTADO PARA EJECUTAR CON CLIENTE

	//creo el thread que recibe las teclas y mueve los jugadores...
	if (pthread_create(&keysThreadJ2, NULL, recepcionTeclasJ2, NULL) < 0) {
		perror("ERROR no se pudo crear el thread recepcionTeclasJ2");
		return 1;
	}

//revisar///////////////////////////////////////////////
	if(pthread_join(movementThread, NULL))
		if(pthread_join(keysThreadJ1, NULL))
			pthread_join(keysThreadJ2, NULL);
//fin revisar/////////////////////////////////////////

	ganadorPartida = 0;

	std::cout << "VIDAS JUGADOR 1: " << jugador1->vidas << std::endl;
	std::cout << "VIDAS JUGADOR 2: " << jugador2->vidas << std::endl;
	std::cout << "RESCATES JUGADOR 1: " << jugador1->rescates << std::endl;
	std::cout << "RESCATES JUGADOR 2: " << jugador2->rescates << std::endl;

	if(finAbrupto == 0)
	{
		if(jugador1->vidas == 0 || jugador2->rescates == cantidadRescates)
			ganadorPartida = 2;
		else
			if(jugador2->vidas == 0 || jugador1->rescates == cantidadRescates)
				ganadorPartida = 1;
	}
	else
	{
		if(finAbrupto == 1) //se cayo el jugador 1
			ganadorPartida = 2;
		else
			ganadorPartida = 1;
	}

	std::cout << "VIDAS JUGADOR 1: " << jugador1->vidas << std::endl;
	std::cout << "VIDAS JUGADOR 2: " << jugador2->vidas << std::endl;
	std::cout << "RESCATES JUGADOR 1: " << jugador1->rescates << std::endl;
	std::cout << "RESCATES JUGADOR 2: " << jugador2->rescates << std::endl;

	// CODIGO COMENTADO PARA EJECUTAR CON CLIENTE

	 for(int i = 0; i < torneo->cantPartidas; i++)
	 {
		sem_wait(semMemoria);
		if(torneo->partidas[i].pid == miPid){
			if(finAbrupto == 1)
				torneo->jugador[torneo->partidas[i].jugador1].conectado = 0;
			if(finAbrupto == 2)
				torneo->jugador[torneo->partidas[i].jugador2].conectado = 0;

			torneo->partidas[i].jugadorGanador = ganadorPartida;
			std::cout << "GANADOR SP (ganadorPartida): " << ganadorPartida << std::endl;
			std::cout << "GANADOR SP (shm): " << torneo->partidas[i].jugadorGanador << std::endl;
		}
		sem_post(semMemoria);
	}


	 liberarRecursos();

		std::cout << "PASO LIBERAR    "<< std::endl;

	delete[] barriles;
	delete[] fuegos;
	delete mono;
	delete fuegoFijoIzq;
	delete fuegoFijoDer;
	delete jugador1;
	delete jugador2;
	delete commSocket_J1;
	delete commSocket_J2;

	//	partida.mostrarGrilla();

	exit(0);
}

